Skip to contentMethod: static {...}
1: /**
2: * Copyright (C) 2020 Czech Technical University in Prague
3: *
4: * This program is free software: you can redistribute it and/or modify it under
5: * the terms of the GNU General Public License as published by the Free Software
6: * Foundation, either version 3 of the License, or (at your option) any
7: * later version.
8: *
9: * This program is distributed in the hope that it will be useful, but WITHOUT
10: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11: * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
12: * details. You should have received a copy of the GNU General Public License
13: * along with this program. If not, see <http://www.gnu.org/licenses/>.
14: */
15: package cz.cvut.kbss.ontodriver.sesame;
16:
17: import cz.cvut.kbss.ontodriver.sesame.connector.Connector;
18: import cz.cvut.kbss.ontodriver.sesame.exceptions.SesameDriverException;
19: import cz.cvut.kbss.ontodriver.descriptor.ReferencedListDescriptor;
20: import cz.cvut.kbss.ontodriver.descriptor.ReferencedListValueDescriptor;
21: import cz.cvut.kbss.ontodriver.model.NamedResource;
22: import org.eclipse.rdf4j.model.IRI;
23: import org.eclipse.rdf4j.model.Resource;
24: import org.eclipse.rdf4j.model.Statement;
25: import org.eclipse.rdf4j.model.ValueFactory;
26:
27: import java.util.ArrayList;
28: import java.util.Collection;
29: import java.util.Iterator;
30: import java.util.List;
31:
32: public class ReferencedListHandler extends
33: ListHandler<ReferencedListDescriptor, ReferencedListValueDescriptor> {
34:
35: private int sequenceCounter = 0;
36:
37: ReferencedListHandler(Connector connector, ValueFactory vf) {
38: super(connector, vf);
39: }
40:
41: @Override
42: SesameIterator createIterator(ReferencedListDescriptor listDescriptor) throws SesameDriverException {
43: return new ReferencedListIterator(listDescriptor, connector, vf);
44: }
45:
46: @Override
47: IRI createListHead(ReferencedListValueDescriptor listValueDescriptor,
48: Collection<Statement> statements) throws SesameDriverException {
49: final IRI owner = owner(listValueDescriptor);
50: final IRI hasList = hasList(listValueDescriptor);
51: final IRI hasContent = hasContent(listValueDescriptor);
52: final IRI context = context(listValueDescriptor);
53: final IRI nodeUri = generateSequenceNode(owner, context);
54: statements.add(vf.createStatement(owner, hasList, nodeUri, context));
55: final IRI nodeContent = sesameIri(listValueDescriptor.getValues().get(0).getIdentifier());
56: statements.add(vf.createStatement(nodeUri, hasContent, nodeContent, context));
57: return nodeUri;
58: }
59:
60: private IRI hasContent(ReferencedListDescriptor listDescriptor) {
61: return sesameIri(listDescriptor.getNodeContent().getIdentifier());
62: }
63:
64: private IRI generateSequenceNode(IRI owner, IRI context) throws SesameDriverException {
65: final String uriBase = owner.stringValue();
66: boolean unique;
67: IRI node;
68: do {
69: node = vf.createIRI(uriBase + "-SEQ_" + sequenceCounter++);
70: final Collection<Statement> stmts = connector.findStatements(node, null, null, false,
71: context);
72: unique = stmts.isEmpty();
73: } while (!unique);
74: return node;
75: }
76:
77: @Override
78: List<Statement> createListRest(IRI headNode, ReferencedListValueDescriptor listValueDescriptor)
79: throws SesameDriverException {
80: final IRI owner = owner(listValueDescriptor);
81: final IRI hasNext = hasNext(listValueDescriptor);
82: final IRI hasContent = hasContent(listValueDescriptor);
83: final IRI context = context(listValueDescriptor);
84: IRI previous = headNode;
85: final List<Statement> statements = new ArrayList<>(
86: listValueDescriptor.getValues().size() * 2);
87: final Iterator<NamedResource> it = listValueDescriptor.getValues().iterator();
88: // Skip the first element, it is already in the head
89: it.next();
90: while (it.hasNext()) {
91: final IRI content = sesameIri(it.next().getIdentifier());
92: previous = createListNode(owner, hasNext, hasContent, content, context, previous, statements);
93: }
94: return statements;
95: }
96:
97: private IRI createListNode(IRI owner, IRI hasNext, IRI hasContent, IRI content, IRI context, Resource previous,
98: Collection<Statement> statements) throws SesameDriverException {
99: final IRI node = generateSequenceNode(owner, context);
100: statements.add(vf.createStatement(previous, hasNext, node, context));
101: statements.add(vf.createStatement(node, hasContent, content, context));
102: return node;
103: }
104:
105: @Override
106: void clearList(ReferencedListValueDescriptor listDescriptor) throws SesameDriverException {
107: final IRI hasNext = hasNext(listDescriptor);
108: final IRI hasContent = hasContent(listDescriptor);
109: final boolean includeInferred = listDescriptor.getListProperty().isInferred();
110: final IRI context = context(listDescriptor);
111: Resource previous = owner(listDescriptor);
112: IRI currentProperty = hasList(listDescriptor);
113: final Collection<Statement> toRemove = new ArrayList<>();
114: Collection<Statement> next;
115: do {
116: next = connector.findStatements(previous, currentProperty, null, includeInferred, context);
117: if (!next.isEmpty()) {
118: final Resource node = extractListNode(next, currentProperty);
119: toRemove.addAll(next);
120: toRemove.addAll(connector.findStatements(node, hasContent, null, includeInferred, context));
121: previous = node;
122: }
123: currentProperty = hasNext;
124: } while (!next.isEmpty());
125: connector.removeStatements(toRemove);
126: }
127:
128: @Override
129: SesameIterator iterator(ReferencedListValueDescriptor listDescriptor) throws SesameDriverException {
130: return new ReferencedListIterator(listDescriptor, connector, vf);
131: }
132:
133: @Override
134: MergeResult mergeWithOriginalList(ReferencedListValueDescriptor listDescriptor, SesameIterator it)
135: throws SesameDriverException {
136: int i = 0;
137: Resource node = null;
138: while (it.hasNext() && i < listDescriptor.getValues().size()) {
139: node = it.nextNode();
140: final Resource content = it.currentContent();
141: final NamedResource newNode = listDescriptor.getValues().get(i);
142: if (!content.stringValue().equals(newNode.getIdentifier().toString())) {
143: it.replaceCurrentWith(newNode);
144: }
145: i++;
146: }
147: return new MergeResult(i, node);
148: }
149:
150: @Override
151: void appendNewNodes(ReferencedListValueDescriptor listDescriptor, MergeResult mergeResult)
152: throws SesameDriverException {
153: int i = mergeResult.i;
154: Resource previous = mergeResult.previous;
155: final IRI owner = owner(listDescriptor);
156: final IRI hasNext = hasNext(listDescriptor);
157: final IRI hasContent = hasContent(listDescriptor);
158: final IRI context = context(listDescriptor);
159: assert i > 0;
160: final Collection<Statement> toAdd = new ArrayList<>((listDescriptor.getValues().size() - i) * 2);
161: while (i < listDescriptor.getValues().size()) {
162: final IRI content = sesameIri(listDescriptor.getValues().get(i).getIdentifier());
163: previous = createListNode(owner, hasNext, hasContent, content, context, previous, toAdd);
164: i++;
165: }
166: connector.addStatements(toAdd);
167: }
168: }